package com.googlecode.dgwt.rebind.feature;

import java.io.File;
import java.io.PrintWriter;

import com.google.gwt.core.ext.GeneratorContext;
import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.core.ext.TreeLogger.Type;
import com.google.gwt.core.ext.typeinfo.JClassType;
import com.google.gwt.core.ext.typeinfo.TypeOracle;
import com.google.gwt.user.rebind.ClassSourceFileComposerFactory;
import com.google.gwt.user.rebind.SourceWriter;
import com.googlecode.dgwt.client.dojo.Feature.ClassType;
import com.googlecode.dgwt.rebind.base.DoubleSourceWriter;

public class FeatureClassTypeSourceCreator extends FeatureSourceCreator {

    
    public static final String FEATURE_CLASSTYPE_NAME = ClassType.class.getName().replace('$', '.');
    
    
    private SourceWriter writer;
    private ClassInfo targetInfo;
    
    
    public FeatureClassTypeSourceCreator(GeneratorContext context, TreeLogger logger, TypeOracle typeOracle) {
        super(context, logger, typeOracle);
    }

    
    @Override
    public String emitClass(JClassType targetClass) throws UnableToCompleteException {
        
        
        JClassType implClass = targetClass.getEnclosingType();
        
        if (implClass == null || !featureClass.isAssignableFrom(implClass)) {
            throw error(logger, "ClassType should be declared inside a Feature descendent");
        }
        
        targetInfo = new ClassInfo(targetClass, targetClass);
        targetInfo.setNewClassName(targetClass.getName().replace('.', '_') + "_DGWT_Feature_ClassType_Impl");
        targetInfo.setGetterName("super");

        String fullImplClassName = super.emitClass(implClass);
        PrintWriter pw = context.tryCreate(logger, packageName, targetInfo.getNewClassName());

        if (pw != null) {
            ClassSourceFileComposerFactory factory = new ClassSourceFileComposerFactory(packageName, targetInfo.getNewClassName());
            
            if (targetClass.isInterface() != null) {
                factory.addImplementedInterface(targetClass.getQualifiedSourceName());
            } else {
                factory.setSuperclass(targetClass.getQualifiedSourceName());
            }
            
            
            writer = factory.createSourceWriter(context, pw);
            
            // FIXME  remover em produção
            try {
                File file = new File("C:/Workspace/WELL/Temp/" + packageName.replace('.', '/') + "/");
                file.mkdirs();
                writer = new DoubleSourceWriter(writer, factory.createSourceWriter(new PrintWriter(new File(file, targetInfo.getNewClassName() + ".java"))));
            } catch (Exception e) {
                logger.log(Type.WARN, e.getMessage());
            }
            
            if (fullImplClassName == null) {
                fullImplClassName = super.getTargetClass().getQualifiedSourceName();
            }
            
            writer.println();
            writer.println("public Class<?> getMainClass(){");
            writer.println("return " + fullImplClassName + ".class;");
            writer.println("}");
            writer.println();
            
            if (fullImplClassName.matches(".*MainTest.*")) {
            writer.println("public "+fullImplClassName+" create(){");
            writer.println(fullImplClassName + " a = new " + fullImplClassName + "();");
            writer.println("a.create();");
            writer.println("return a;");
            writer.println("}");
            writer.println();
            }

            writer.commit(logger);
        }

        return packageName + "." + targetInfo.getNewClassName();
    }

    
}
